package Be_greedy_for_snakes;

import javax.swing.*;         //swing是一个用于开发java图形界面应用程序的开发工具包；javax表示为java拓展包，不是核心包；
import java.awt.*;            //引入AWT包，因为要使用到颜色类
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.LinkedList;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

public class MainFramer extends JFrame implements ActionListener {       //MainFrame继承JFrame窗体;JFrame为swing的顶层独立显示组件

    public Snake snake;   //蛇的成员变量
    public Timer timer;   //定时器，在规定的时间内调用蛇的节点移动
    public JPanel jPanel; //棋盘的成员变量
    public Node food;     //食物节点
    public Music music;    //音乐
    public Obstacle obstacles;//障碍物
    public Word word;   //字母
    public char[] arry=new char[5];       //面板上存储字母的数组
    public char[] arry1=new char[100];

    public String str;
    public int x;
    public int y=0;
    public int z=0;
    public String path = "file/";   //用来存放路径

    //创建选项下拉菜单选项的对象
    JMenuItem EndlessmodejMenu = new JMenuItem("无尽模式");
    JMenuItem WordmodejMenu = new JMenuItem("单词模式");
    JMenuItem DisordermodejMenu = new JMenuItem("障碍模式");
    //游戏模式下的菜单选项

    JMenuItem replayjMenuItem = new JMenuItem("重新开始");
    JMenuItem reloginjMenuItem = new JMenuItem("重新登录");
    JMenuItem closejMenuItem = new JMenuItem("退出游戏");

    JMenuItem contactjMenuItem = new JMenuItem("联系方式");



    public MainFramer(){
        initMFrame();//初始化窗口
        initPanel();//初始化游戏棋盘
        initSnake();//初始化蛇
        initTimer();//初始化定时器
        initMusic();//初始化音乐
        setKeyboardcontrol();//设置键盘控制
        initObstacle();//设置障碍物
        initWord(z++);//初始化字母
        initFood();//初始化食物
        initJMenuBar();//初始化菜单
        this.setVisible(true);//setVisible(boolean)方法是用来显示/隐藏GUI组件的
    }

    private void initJMenuBar() {
        //创建整个菜单的对象
        JMenuBar jMenuBar = new JMenuBar();

        //创建菜单上两个选项的对象（功能    关于我们）
        JMenu functionjMenu = new JMenu("功能");
        JMenu aboutjMenu = new JMenu("关于我们");

        //创建游戏模式的菜单选项
        JMenu GamemodejMenu = new JMenu("游戏模式");

        //将单词模式，障碍模式，无尽模式添加到游戏模式中
        GamemodejMenu.add(WordmodejMenu);
        GamemodejMenu.add(EndlessmodejMenu);
        GamemodejMenu.add(DisordermodejMenu);

        //将下拉菜单选项添加到选项中
        functionjMenu.add(GamemodejMenu);
        functionjMenu.add(replayjMenuItem);
        functionjMenu.add(reloginjMenuItem);
        functionjMenu.add(closejMenuItem);

        aboutjMenu.add(contactjMenuItem);

        GamemodejMenu.add(WordmodejMenu);
        //给每个菜单下拉选项添加事件
        EndlessmodejMenu.addActionListener(this);
        WordmodejMenu.addActionListener(this);
        DisordermodejMenu.addActionListener(this);
        replayjMenuItem.addActionListener(this);
        reloginjMenuItem.addActionListener(this);
        closejMenuItem.addActionListener(this);
        contactjMenuItem.addActionListener(this);

        //将选项添加到菜单中
        jMenuBar.add(functionjMenu);
        jMenuBar.add(aboutjMenu);

        //将菜单添加到游戏界面中
        this.setJMenuBar(jMenuBar);
    }

    private void initAlphabet(int y){
        Random r=new Random();
        if(y==0) {
            x = r.nextInt(word.getAlphabet1().size());
            str = word.getAlphabet1().get(x);
        }
    }

    private void initObstacle(){
        obstacles=new Obstacle();
        obstacles.random();
        while (true) {       //防止障碍物生成在蛇头处
            int flag=0;
            LinkedList<Node> o = obstacles.getObstacle();
            for (Node node : o) {
                if(node.getX()==snake.getBody().getFirst().getX()&&node.getY()==snake.getBody().getFirst().getY()){
                    flag=1;
                    obstacles.random();
                    break;
                }
            }
            if(flag==0) {
                break;
            }
        }
    }

    private void initWord(int z){
        word=new Word();
        initAlphabet(y++);
        word.random();

        if(word!=null) {
            LinkedList<Node> wd = word.getWord();
            int i=0;
            for (Node node : wd) {
                if(i==0){
                    arry[i++]=word.getAlphabet().get(x).charAt(z);
                }
                else {
                    Random r=new Random();
                    arry[i++] = (char) (r.nextInt((90-65)+1)+65);
                }
            }
        }
        while (true) {                //防止字母生成在障碍物中
            int flag=0;
            LinkedList<Node> o = obstacles.getObstacle();
            LinkedList<Node> w= word.getWord();
            for(Node node : w) {
                for (Node node1 : o) {
                    if (node1.getX() == node.getX() && node1.getY() == node.getY()) {
                        flag = 1;
                        word.random();
                        break;
                    }
                }
                if(flag==1){
                    break;
                }
            }
            if (flag == 0) {
                break;
            }
        }
    }

    private void initFood() {
        food = new Node();
        food.random();
        while (true) {                      //防止食物生成在障碍物中
            int flag=0;
            LinkedList<Node> o = obstacles.getObstacle();
            for (Node node : o) {
                if(node.getX()==food.getX()&&node.getY()==food.getY()){
                    flag=1;
                    food.random();
                    break;
                }
            }
            if(flag==0) {
                break;
            }
        }
        while (true) {                     //防止食物生成在字母中
            int flag=0;
            LinkedList<Node> wd = word.getWord();
            for (Node node : wd) {
                if(node.getX()==food.getX()&&node.getY()==food.getY()){
                    flag=1;
                    food.random();
                    break;
                }
            }
            if(flag==0) {
                break;
            }
        }
    }

    public void setKeyboardcontrol() {                  //让键盘控制蛇的方法
        addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {         //KeyEvent类中的方法可以实现键盘控制
                switch (e.getKeyCode()){
                    case KeyEvent.VK_UP:
                        if(snake.getDirection()!=Direction.DOWN){        //键盘按下的不为DOWN才可以执行操作，以下同理
                            snake.setDirection(Direction.UP);
                        }
                        break;
                    case KeyEvent.VK_DOWN:
                        if(snake.getDirection()!=Direction.UP){
                            snake.setDirection(Direction.DOWN);
                        }
                        break;
                    case KeyEvent.VK_LEFT:
                        if(snake.getDirection()!=Direction.RIGHT){
                            snake.setDirection(Direction.LEFT);
                        }
                        break;
                    case KeyEvent.VK_RIGHT:
                        if(snake.getDirection()!=Direction.LEFT){
                            snake.setDirection(Direction.RIGHT);
                        }
                        break;
                    case KeyEvent.VK_SPACE:
                        if(snake.isLiving()){
                            snake.setLiving(false);
                        }
                        else{
                            snake.setLiving(true);
                        }
                        break;
                }
            }
        });
    }

    public void initMusic() {                   //播放背景音乐的方法
        music = new Music(path + "music/manhua.wav");
        music.start();
    }

    int flag=0,index=0,size;
    private void initTimer() {                  //定时器方法
        timer = new Timer();
        //初始化定时任务
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                snake.move();

                Node first = snake.getBody().getFirst();
                //吃食物
                if(food!=null) {
                    if (first.getX() == food.getX() && first.getY() == food.getY()) {     //利用蛇头节点坐标和食物节点坐标来判断是否吃到
                        InstantMusic music = new InstantMusic(path + "music/ji.wav");
                        music.start();        //在吃掉食物后，播放提示音
                        snake.eat(food);
                        initFood();       //在每次吃掉食物后，更新食物节点位置
                    }
                }
                //吃字母
                if(word!=null) {
                    if (word.getWord() != null) {
                        LinkedList<Node> wd=word.getWord();
                        int i=0;
                        for(Node node : wd) {

                            if(first.getX()==node.getX()&&first.getY()==node.getY()) {
                                arry1[index++]=arry[i];
                                if(arry[0]==arry[i]){
                                    flag++;
                                }
                                else{
                                    flag=-1;
                                }

                                snake.eat(node);
                                snake.setScore(snake.getScore()+5);
                                if(flag==word.getAlphabet().get(x).length()) {
                                    /*
                                    try{
                                        Thread.sleep(1000*10);//让当前线程睡眠十秒钟

                                    }catch (InterruptedException e){
                                        e.printStackTrace();
                                        //恢复中断的线程
                                        Thread.currentThread().interrupt();
                                    }
                                     */
                                    snake.setScore(snake.getScore()+50);
                                    size=flag;
                                    y=0;
                                    initAlphabet(y++);

                                }
                                else if(flag==-1){
                                    snake.setScore(snake.getScore()-30);
                                    z=0;
                                }
                                System.out.println(flag+"  "+word.getAlphabet().get(x).length());
                                if(z+1==word.getAlphabet().get(x).length()){
                                    snake.setScore(snake.getScore()+10);
                                    initWord(z);
                                    z=0;
                                }
                                else {
                                    initWord(z++);
                                }
                                break;
                            }
                            i++;
                        }
                    }
                }
                jPanel.repaint();      //重绘棋盘，每移动一个节点，就重绘一次棋盘
            }
        };
        timer.scheduleAtFixedRate(timerTask,0,100);
    }

    private void initSnake() {
        snake = new Snake();
    }

    private void initPanel(){
        jPanel = new JPanel(){                 //jpanel对象
            @Override                          //paint可以绘制棋盘中的内容
            public void paint(Graphics g) {    //Graphics g可以看作是画笔，它提供很多方法，用来绘制棋盘
                g.clearRect(0,0,1310,740);

                //背景
                Image img1 = this.getToolkit().getImage(path + "image/background.jpg");
                g.drawImage(img1,0,0,1310,740,this);//绘制图片方法

                //绘制侧边框内容
                Font font=new Font("微软雅黑",Font.BOLD,20);//设置字母的大小和样式
                g.setFont(font);
                g.setColor(Color.RED);//设置字体的颜色
                g.drawString("请将中文翻译为英文",52*20,1*20);
                g.drawString("并按顺序拼写:",52*20,2*20);
                g.drawString(str, 52*20 , 3*20);             //在侧边栏绘制中文
                g.drawString("得分为：",52*20,4*20);
                g.drawString(snake.getScore()+"",52*22,4*20);

                //绘制蛇的身体
                LinkedList<Node> body = snake.getBody();     //通过getBody方法拿到集合
                for (Node node : body) {                     //对集合遍历
                    if(node == body.getFirst()){//取出头结点,对蛇头朝向的四个方向分别插入四张不同的图片
                        if(snake.getDirection()==Direction.LEFT){
                            Image img2 = this.getToolkit().getImage(path + "image/headleft.jpg");
                            g.drawImage(img2,node.getX()*20,node.getY()*20,20,20,this);
                        }
                        else if(snake.getDirection()==Direction.RIGHT){
                            Image img2 = this.getToolkit().getImage(path + "image/headright.jpg");
                            g.drawImage(img2,node.getX()*20,node.getY()*20,20,20,this);
                        }
                        else if(snake.getDirection()==Direction.UP){
                            Image img2 = this.getToolkit().getImage(path + "image/headup.jpg");
                            g.drawImage(img2,node.getX()*20,node.getY()*20,20,20,this);
                        }
                        else if(snake.getDirection()==Direction.DOWN){
                            Image img2 = this.getToolkit().getImage(path + "image/headdown.jpg");
                            g.drawImage(img2,node.getX()*20,node.getY()*20,20,20,this);
                        }
                    }
                    else {
                        Image img3 = this.getToolkit().getImage(path + "image/body.jpg");
                        g.drawImage(img3, node.getX()*20, node.getY()*20, 20, 20, this);//绘制图片方法
                    }
                }

                //绘制食物
                Image img4 = this.getToolkit().getImage(path + "image/food.jpg");
                g.drawImage(img4,food.getX()*20,food.getY()*20,20,20,this);//绘制图片方法

                //绘制障碍物
                LinkedList<Node> ob = obstacles.getObstacle();
                for(Node node : ob) {
                    Image img5 = this.getToolkit().getImage(path + "image/boom.png");
                    g.drawImage(img5, node.getX() * 20, node.getY() * 20, 20, 20, this);
                }

                //判断蛇撞到障碍物后死亡
                Node first=snake.getBody().getFirst();
                for (int i = 0; i < obstacles.getObstacle().size(); i++) {
                    Node node = obstacles.getObstacle().get(i);
                    if (first.getX() == node.getX() && first.getY() == node.getY()) {
                        snake.setLiving(false);
                    }
                }

                //绘制字母
                if(word!=null) {
                    LinkedList<Node> wd = word.getWord();
                    int i=0;
                    for (Node node : wd) {
                        g.drawString(arry[i++]+ "", node.getX()*20 , (node.getY()+1)*20);
                    }
                }

                //在侧边框绘制吃到的字母排序
                StringBuffer str1=new StringBuffer();
                for(int i=0;i<index;i++){
                    if(arry1[i]!='\0'){
                        str1.append(arry1[i]);
                    }
                }
                g.drawString(str1.toString(), 52*20, 6*20);

                if(flag==size){
                    //g.drawString("拼写正确,即将进入奖励关卡!",52*20,8*20);
                    flag=0;
                    arry1=new char[100];
                    size=word.getAlphabet().get(x).length();
                }
                else if(flag==-1){
                    flag=0;
                    arry1=new char[100];
                    //g.drawString("拼写错误,即将进入惩罚关卡!",52*20,8*20);
                }
            }
        };
        add(jPanel);//将绘制的内容添加到窗口中
    }

    private void initMFrame() {
        setSize(1310,740);//设置窗体宽高
        setLocationRelativeTo(null);//设置窗体居中
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭按钮为正常关闭窗口
        setTitle("贪吃蛇小游戏单机版 V3.0");//设置窗口标题
        setAlwaysOnTop(true);//设置窗体保持置顶
        setResizable(false);//设置窗口大小不可变
    }

    public JPanel getjPanel() {
        return jPanel;
    }

    public void setjPanel(JPanel jPanel) {
        this.jPanel = jPanel;
    }

    public Snake getSnake() {
        return snake;
    }

    public void setSnake(Snake snake) {
        this.snake = snake;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        //获取当前被点击菜单的对象
        Object obj = e.getSource();
        //判断
        if(obj==replayjMenuItem){  //重新开始游戏
            new MainFramer();
            setVisible(false);
        }
        else if(obj==reloginjMenuItem){   //重新登录
            setVisible(false);//关闭当前界面
            new LoginFrame();//打开登录界面
        }
        else if(obj==closejMenuItem){   //关闭游戏
            System.exit(0);//关闭虚拟机
        }
        else if(obj==contactjMenuItem){    //关于我们
            JDialog jDialog = new JDialog();//创建一个弹窗对象
            JLabel jLabel = new JLabel(new ImageIcon("file/image/contact.jpg"));
            jLabel.setBounds(0,0,216,447);//设置位置和宽高
            jDialog.getContentPane().add(jLabel);//将图片放入弹框中
            jDialog.setSize(300,400);//设置弹框大小
            jDialog.setAlwaysOnTop(true);//设置弹框置顶
            jDialog.setLocationRelativeTo(null);//设置弹框居中
            jDialog.setModal(true);//必须关闭弹窗才能进行其他操作
            jDialog.setTitle("关于我们");//设置弹窗标题
            jDialog.setVisible(true);//显示弹框
        }
    }
}
